using System;
using System.Collections;
using System.Collections.Generic;
using Actions;
using Globals.States;
using UI;
using UnityEngine;
using UnityEngine.InputSystem;

namespace Controls
{
    public class PlayerController : MonoBehaviour
    {
        public event Action StartGamePerformed;
        public event Action RestartPerformed;
        public event Action MoveCursorPerformed;
        public event Action ShootPerformed;
        public event Action PausePerformed;
        
        [SerializeField] private float minMoveCursorInterval = 0.8f;
        
        private GameControls _controls;
        
        private TargetSelector _targetSelector;
        private Shooter _shooter;
        
        private readonly float _inputDeadZone = 0.1f;

        private float _moveCursorCooldownTimer;
        
        
        private void Awake()
        {
            _controls = new GameControls();

            _targetSelector = GetComponent<TargetSelector>();
            _shooter = GetComponent<Shooter>();
        }

        private void OnEnable()
        {
            _controls.UI.StartGame.performed += StartGame_performed;
            _controls.UI.Restart.performed += Restart_performed;
            _controls.Gameplay.MoveCursor.performed += MoveCursor_performed;
            _controls.Gameplay.Shoot.performed += Shoot_clicked;
            _controls.UI.Menu.performed += Pause_clicked;
            _controls.Enable();
        }

        private void OnDisable()
        {
            _controls.UI.StartGame.performed -= StartGame_performed;
            _controls.UI.Restart.performed -= Restart_performed;

            _controls.Gameplay.Shoot.performed -= Shoot_clicked;
            _controls.UI.Menu.performed -= Pause_clicked;
            _controls.Disable();
        }

        private void Update()
        {
            if (_moveCursorCooldownTimer > 0f)
            {
                _moveCursorCooldownTimer -= Time.deltaTime;
            }
            else
            {
                HandleMoveCursor();
            }
        }

        public void OnGameOver()
        {
            _controls.Gameplay.Disable();
        }

        private void HandleMoveCursor()
        {
            if (GameState.Instance.CurrentState is not TutorialState &&
                GameState.Instance.CurrentState is not GameStartedState)
            {
                return;
            }
            
            Vector2 input = _controls.Gameplay.MoveCursor.ReadValue<Vector2>();

            if (Mathf.Abs(input.x) <= _inputDeadZone && 
                Mathf.Abs(input.y) <= _inputDeadZone)
            {
                return;
            }
            
            _targetSelector.TryMoveCursor(input);
            _moveCursorCooldownTimer = minMoveCursorInterval;
        }
        
        private void Restart_performed(InputAction.CallbackContext obj)
        {
            RestartPerformed?.Invoke();
        }
        
        private void MoveCursor_performed(InputAction.CallbackContext obj)
        {
            MoveCursorPerformed?.Invoke();
        }
        
        private void StartGame_performed(InputAction.CallbackContext obj)
        {
            StartGamePerformed?.Invoke();
        }

        private void Pause_clicked(InputAction.CallbackContext obj)
        {
            PausePerformed?.Invoke();
        }

        private void Shoot_clicked(InputAction.CallbackContext obj)
        {
            if (GameState.Instance.CurrentState is not TutorialState &&
                GameState.Instance.CurrentState is not GameStartedState)
            {
                return;
            }
            
            _shooter.Shoot();
            ShootPerformed?.Invoke();
        }
    }
}
